package planificador;

import java.util.ArrayList;
import java.util.List;

public class RoundRobin {
        //Atributos 
	int quantum;
	int ttProceso=0,contcpu;
        
	public RoundRobin(List c,int mem){ //R.R Recibe la lista de procesos (Id,nombre y rafaga) asi como el tamaño maximo de la memoria (max)
		
		quantum = Teclado.natural(1,"Ingrese el tamaño del Quantum: ");// Se guarda el Quantum
                ArrayList terminados=new ArrayList(); //Se genera una lista donde se almacenaran los procesos terminados
		//Lista con Tiempos de Rafaga
		Proceso aux = new Proceso(); // Instancia de Proceso
			for(int i = 0;i < c.size();i++){
				aux = (Proceso) c.get(i); //Almacenamos cada proceso de la lista en aux y con un "cast" aaeguramos que el elemento obtenido sea de tipo Proceso
				ttProceso += aux.getRafaga();//Se suma el tiempo de rafaga asignado anteriormente al proceso y guardo su tiempo total.
			}
			for(contcpu = 0;contcpu < ttProceso; contcpu++){  //lleva un contador del tiempo actual
                                //Asignacion de memoria
                            int tam=0; 
                            if (!c.isEmpty()){  ////El primer elemento de la lista siempre entrara en ejecucion
                                aux = (Proceso) c.get(0);//Se obtiene el primer elemento de la lista
                                aux.setEstado("Ejecución");  //Se asigna el estado de Ejecucion
                            }
                            for(int i = 1;i < c.size();i++ ){
                                     aux = (Proceso) c.get(i); //Almacenamos cada proceso de la lista en aux y con un "cast" aaeguramos que el elemento obtenido sea de tipo Proceso
                                     if("Listo".equals(aux.getEstado()) || "Listo para ejecución".equals(aux.getEstado()))
                                     tam+=aux.getTamano();//Obtenemos y alamcenamos el tamaño del proceso que se encuentre en Listo o Listo para Ejecuacion
                                     if (tam<=mem){ //Si el proceso cabe aun en la memoria, se le cambia su estado.
                                         aux.setEstado("Listo para ejecución"); 
                                     }
                                     else
                                         break;
                            }
                            
                            //Imprime como estan los procesos en el tiempo contcpu
                            System.out.println("En el tiempo "+contcpu+":");
                            for(int i = 0;i < c.size();i++ ){ 
                                aux = (Proceso) c.get(i); //Almacenamos cada proceso de la lista en aux y con un "cast" aaeguramos que el elemento obtenido sea de tipo Proceso
                                System.out.println(aux.getNombre()+"\tTamaño:"+aux.getTamano()+"\tTiempo restante:"+aux.getRafaga()+"\tEstado:"+aux.getEstado()); //Imprimimos cada Proceso (id, nombre, tamaño y rafaga) en cada tiempo de ejecucion del CPU
                                }
                            for(int i = 0;i < terminados.size();i++ ){ 
                                aux = (Proceso) terminados.get(i); //Almacenamos cada proceso terminado de la lista en aux y con un "cast" aaeguramos que el elemento obtenido sea de tipo Proceso
                                System.out.println(aux.getNombre()+"\tTamaño:"+aux.getTamano()+"\tTiempo restante:"+aux.getRafaga()+"\tEstado:"+aux.getEstado()); //Imprimimos cada Proceso terminado (id, nombre, tamaño y rafaga) durante cada tiempo de ejecucion del CPU
                                }
                            
                            //Dentro del CPU
                            aux = (Proceso) c.get(0);//Obtengo el primer elemento de la lista
                            
                            // Para poder restar , se determina primero si a la rafaga del proceso 
                            //se le resta su propia rafaga( en casa de q esta sea menor q el quantum) 
                            //o bien si se le resta el valor del quantum (en caso que dicha rafaga sea mayor que el quantum)
                            int aux3= aux.getRafaga()-quantum;
                            
                            if(aux3<0)
                                aux3=aux.getRafaga();
                            else
                                aux3=quantum;
                                //Retardo para poder Visualizar la Simulacion
//                            try{
//                                    Thread.sleep(3000);
//                                }catch(InterruptedException e){}
                            
                            Teclado.enter("");
                            aux.setRafaga(aux.getRafaga()-aux3);// A cada proceso de la lista se le asigna el valor restante de su rafaga
                            contcpu+=aux3-1; //Aumentamos el contador del tiempo actual el tiempo transcurrido de ejecucion por cada proceso (quantum o rafaga)
                                                //se le resta 1 ya que al finalizar el for siempre aumenta 1
                            if(aux.getRafaga()==0){//verifico que el proceso ya haya terminado su rafaga
                                aux.setEstado("Terminado"); //Una vez terminado le asignamos el estado de Terminado
                                c.remove(0);//Al proceso terminado lo removemos de la lista
                                terminados.add(aux); //Almacenamos cada proceso terminado en la lista Terminados
                            }
                            else{
                                c.remove(0);
                                aux.setEstado("Listo");//Si no termino el proceso le asignamos el estado de Listo
                                c.add(aux);//El proceso lo mandamos a la lista de los procesos Listos nuevamente
                            }
                        }
                    //Imprime el ultimo tiempo
                     //Se imprime cada proceso con sus atributos correspondientes y sus estados durante el tiempo del CPU
            System.out.println("En el tiempo "+contcpu+":");
                for(int i = 0;i < c.size();i++ ){ 
                    aux = (Proceso) c.get(i); //Almacenamos cada proceso de la lista en aux y con un "cast" aaeguramos que el elemento obtenido sea de tipo Proceso
                    System.out.println(aux.getNombre()+"\tTamaño:"+aux.getTamano()+"\tTiempo restante:"+aux.getRafaga()+"\tEstado:"+aux.getEstado());
                }
                for(int i = 0;i < terminados.size();i++ ){ 
                    aux = (Proceso) terminados.get(i); //Almacenamos cada proceso terminado de la lista en aux y con un "cast" aaeguramos que el elemento obtenido sea de tipo Proceso
                    System.out.println(aux.getNombre()+"\tTamaño:"+aux.getTamano()+"\tTiempo restante:"+aux.getRafaga()+"\tEstado:"+aux.getEstado());
                }
            
        }
}
